package com.life.controller;

import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.JOptionPane;

import com.life.model.LifeModel;
import com.life.rule.ILifeRule;
import com.life.rule.ProbabilisticLifeRule;
import com.life.rule.SBLifeRule;
import com.life.rule.UserDefinedRule;
import com.life.utils.DialogUtil;
import com.life.view.AbstractAdapter;
import com.life.view.ButtonAdapter;
import com.life.view.RadioButtonAdapter;
import com.life.view.RadioGroupAdapter;
import com.life.view.TextFieldAdapter;
import com.life.view.ColorGenerator;


public class RuleController extends AbstractController {

	ILifeRule currentRule = new SBLifeRule();
	ILifeRule firstSavedLifeRule = null;
	ILifeRule secondSavedLifeRule = null;
	ILifeRule thirdSavedLifeRule = null;
	
	RadioGroupAdapter groupAdapter = null;
	AbstractAdapter userBAdapter= null;
	AbstractAdapter userSAdapter= null;
	AbstractAdapter s0Adapter= null;
	AbstractAdapter s1Adapter= null;
	AbstractAdapter s2Adapter= null;
	AbstractAdapter s3Adapter= null;
	AbstractAdapter s4Adapter= null;
	AbstractAdapter s5Adapter= null;
	AbstractAdapter s6Adapter= null;
	AbstractAdapter s7Adapter= null;
	AbstractAdapter s8Adapter= null;
	AbstractAdapter b0Adapter= null;
	AbstractAdapter b1Adapter= null;
	AbstractAdapter b2Adapter= null;
	AbstractAdapter b3Adapter= null;
	AbstractAdapter b4Adapter= null;
	AbstractAdapter b5Adapter= null;
	AbstractAdapter b6Adapter= null;
	AbstractAdapter b7Adapter= null;
	AbstractAdapter b8Adapter= null;
	AbstractAdapter preset1Adapter = null;
	AbstractAdapter preset2Adapter = null;
	AbstractAdapter preset3Adapter = null;
	AbstractAdapter preset4Adapter = null;
	AbstractAdapter preset5Adapter = null;
	AbstractAdapter preset6Adapter = null;
	AbstractAdapter preset7Adapter = null;
	AbstractAdapter preset8Adapter = null;
	AbstractAdapter preset9Adapter = null;
	RadioButtonAdapter preset10Adapter = null;
	RadioButtonAdapter preset11Adapter = null;
	RadioButtonAdapter preset12Adapter = null;
	AbstractAdapter rulesApplyAdapter  = null;
	AbstractAdapter usePredefAdapter  = null;
	AbstractAdapter useUsrDefAdapter  = null;
	AbstractAdapter usePrblAdapter = null;
	
	ColorGenerator theColorGenerator = ColorGenerator.getInstance();
	
	ILifeRule lifeRule = new SBLifeRule("23","3",theColorGenerator,"Life");
	ILifeRule highLifeRule = new SBLifeRule("23","36",theColorGenerator,"HighLife");
	ILifeRule gnarlRule = new SBLifeRule("1","1",theColorGenerator,"Gnarl");
	ILifeRule mazeRule = new SBLifeRule("12345","3",theColorGenerator,"Maze");
	ILifeRule amoebaRule = new SBLifeRule("34","2",theColorGenerator,"Exploder");
	ILifeRule coagulationRule = new SBLifeRule("235678","378",theColorGenerator,"Coagulation");
	ILifeRule coralRule = new SBLifeRule("45678","3",theColorGenerator,"Coral");
	ILifeRule seisureRule = new SBLifeRule("018","018",theColorGenerator,"Seisure");
	ILifeRule twoByTwoRule = new SBLifeRule("125","36",theColorGenerator,"2 x 2");
	
	HashMap<AbstractAdapter,ILifeRule>presetHash = new HashMap<AbstractAdapter,ILifeRule>();
	
	public RuleController(LifeModel model, ArrayList<AbstractAdapter> adapterList) {
		super(model, adapterList);
		
		theModel.setCurrentRule(currentRule);
		
		
		userBAdapter= adapterList.get(0);
		userSAdapter= adapterList.get(1);
		s0Adapter= adapterList.get(2);
		s1Adapter= adapterList.get(3);
		s2Adapter= adapterList.get(4);
		s3Adapter= adapterList.get(5);
		s4Adapter= adapterList.get(6);
		s5Adapter= adapterList.get(7);
		s6Adapter= adapterList.get(8);
		s7Adapter= adapterList.get(9);
		s8Adapter= adapterList.get(10);
		b0Adapter= adapterList.get(11);
		b1Adapter= adapterList.get(12);
		b2Adapter= adapterList.get(13);
		b3Adapter= adapterList.get(14);
		b4Adapter= adapterList.get(15);
		b5Adapter= adapterList.get(16);
		b6Adapter= adapterList.get(17);
		b7Adapter= adapterList.get(18);
		b8Adapter= adapterList.get(19);
		preset1Adapter = adapterList.get(20);
		preset2Adapter = adapterList.get(21);
		preset3Adapter = adapterList.get(22);
		preset4Adapter = adapterList.get(23);
		preset5Adapter = adapterList.get(24);
		preset6Adapter = adapterList.get(25);
		preset7Adapter = adapterList.get(26);;
		preset8Adapter = adapterList.get(27);
		preset9Adapter = adapterList.get(28);
		preset10Adapter = (RadioButtonAdapter)adapterList.get(29);
		preset11Adapter = (RadioButtonAdapter)adapterList.get(30);
		preset12Adapter = (RadioButtonAdapter)adapterList.get(31);
		rulesApplyAdapter  = adapterList.get(32);
		usePredefAdapter  = adapterList.get(33);
		useUsrDefAdapter  = adapterList.get(34);
		usePrblAdapter = adapterList.get(35);
		
		
	
		setPresets();
	}
	
	public void setPresets()
	{
		
		preset1Adapter.set(lifeRule);
		preset2Adapter.set(highLifeRule);
		preset3Adapter.set(gnarlRule);
		preset4Adapter.set(mazeRule);
		preset5Adapter.set(amoebaRule);
		preset6Adapter.set(coagulationRule);
		preset7Adapter.set(coralRule);
		preset8Adapter.set(seisureRule);
		preset9Adapter.set(twoByTwoRule);
		
		preset10Adapter.setEnabled(false);
		preset11Adapter.setEnabled(false);
		preset12Adapter.setEnabled(false);

		presetHash.put(preset1Adapter,lifeRule);
		presetHash.put(preset1Adapter,lifeRule);
		presetHash.put(preset2Adapter,highLifeRule);
		presetHash.put(preset3Adapter,gnarlRule);
		presetHash.put(preset4Adapter,mazeRule);
		presetHash.put(preset5Adapter,amoebaRule);
		presetHash.put(preset6Adapter,coagulationRule);
		presetHash.put(preset7Adapter,coralRule);
		presetHash.put(preset8Adapter,seisureRule);
		presetHash.put(preset9Adapter,twoByTwoRule);
	}

	@Override
	public void doUpdate(AbstractAdapter adapter, Object data) {
		
		if(adapter instanceof ButtonAdapter)
		{
			setRule();
		}
	}
	
	protected void setPredefinedRule()
	{
		
		AbstractAdapter selectedAdapter = null;
		if(preset1Adapter.isSelected())
		{
			selectedAdapter = preset1Adapter;
		}
		
		if(preset2Adapter.isSelected())
		{
			selectedAdapter = preset2Adapter;
		}
		
		if(preset3Adapter.isSelected())
		{
			selectedAdapter = preset3Adapter;
		}
		
		if(preset4Adapter.isSelected())
		{
			selectedAdapter = preset4Adapter;
		}
		
		if(preset5Adapter.isSelected())
		{
			selectedAdapter = preset5Adapter;
		}
		
		if(preset6Adapter.isSelected())
		{
			selectedAdapter = preset6Adapter;
		}
		
		if(preset7Adapter.isSelected())
		{
			selectedAdapter = preset7Adapter;
		}
		
		if(preset8Adapter.isSelected())
		{
			selectedAdapter = preset8Adapter;
		}
		
		if(preset9Adapter.isSelected())
		{
			selectedAdapter = preset9Adapter;
		}
		
		if(preset10Adapter.isSelected())
		{
			selectedAdapter = preset10Adapter;
		}
		
		if(preset11Adapter.isSelected())
		{
			selectedAdapter = preset11Adapter;
		}
		
		if(preset12Adapter.isSelected())
		{
			selectedAdapter = preset12Adapter;
		}
		
		if(selectedAdapter != null)
		{
			currentRule = presetHash.get(selectedAdapter);
			theModel.setCurrentRule(currentRule);
		}
			
	}
	
	protected void setRule()
	{
		if(usePredefAdapter.isSelected())
		{
			//System.out.println("PREDEFINED IS SELECTED");
			setPredefinedRule();
		}
		else if(useUsrDefAdapter.isSelected())
		{
			setUserDefined();
		}
		else if(usePrblAdapter.isSelected())
		{
			setProbabilisticDefined();
		}
	
	}
	static int userCounter = 0;
	
	protected void setUserDefined()
	{
		try
		{

			String sVal = userSAdapter.get().toString().trim();
			String bVal = userBAdapter.get().toString().trim();

			if(sVal.length() > 0)
			{
				Integer checkS = Integer.parseInt(sVal);
			}

			if(bVal.length() > 0)
			{
				Integer checkB = Integer.parseInt(bVal);
			}

			ILifeRule newRule = new UserDefinedRule(sVal,bVal,
					theColorGenerator,
					"");

			setEnteredRule(newRule);
	}
		catch(NumberFormatException ex)
		{
			DialogUtil.showMessageDialog("Please only enter numeric values");
		}
	}
	
	protected void setEnteredRule(ILifeRule newRule)
	{
		if(firstSavedLifeRule == null)
		{
			firstSavedLifeRule = newRule;
			presetHash.put(preset10Adapter,firstSavedLifeRule);
			preset10Adapter.set(firstSavedLifeRule);
			preset10Adapter.setEnabled(true);
			preset10Adapter.setSelected(true);
		}
		else if(firstSavedLifeRule != null && secondSavedLifeRule == null)
		{
			secondSavedLifeRule = newRule;
			presetHash.put(preset11Adapter,secondSavedLifeRule);
			preset11Adapter.set(secondSavedLifeRule);
			preset11Adapter.setEnabled(true);
			preset11Adapter.setSelected(true);
		}
		else if(firstSavedLifeRule != null && secondSavedLifeRule != null && thirdSavedLifeRule == null)
		{
			thirdSavedLifeRule = newRule;
			presetHash.put(preset12Adapter,thirdSavedLifeRule);
			preset12Adapter.set(thirdSavedLifeRule);
			preset12Adapter.setEnabled(true);
			preset12Adapter.setSelected(true);
		}
		else
		{
			firstSavedLifeRule = secondSavedLifeRule;
			secondSavedLifeRule = thirdSavedLifeRule;
			thirdSavedLifeRule = newRule;
			presetHash.put(preset10Adapter,firstSavedLifeRule);
			presetHash.put(preset11Adapter,secondSavedLifeRule);
			presetHash.put(preset12Adapter,thirdSavedLifeRule);
			preset10Adapter.set(firstSavedLifeRule);
			preset11Adapter.set(secondSavedLifeRule);
			preset12Adapter.set(thirdSavedLifeRule);
			preset12Adapter.setSelected(true);
		}

		currentRule = newRule;
		theModel.setCurrentRule(currentRule);
	}

	protected void setProbabilisticDefined()
	{
		double []sVals = new double[9];
		double []bVals = new double[9];

		try
		{

			sVals[0] = ((new Double(s0Adapter.get().toString().trim()))).doubleValue()/100;
			sVals[1] = ((new Double(s1Adapter.get().toString().trim()))).doubleValue()/100;
			sVals[2] = ((new Double(s2Adapter.get().toString().trim()))).doubleValue()/100;
			sVals[3] = ((new Double(s3Adapter.get().toString().trim()))).doubleValue()/100;
			sVals[4] = ((new Double(s4Adapter.get().toString().trim()))).doubleValue()/100;
			sVals[5] = ((new Double(s5Adapter.get().toString().trim()))).doubleValue()/100;
			sVals[6] = ((new Double(s6Adapter.get().toString().trim()))).doubleValue()/100;
			sVals[7] = ((new Double(s7Adapter.get().toString().trim()))).doubleValue()/100;
			sVals[8] = ((new Double(s8Adapter.get().toString().trim()))).doubleValue()/100;

			bVals[0] = ((new Double(b0Adapter.get().toString().trim()))).doubleValue()/100;
			bVals[1] = ((new Double(b1Adapter.get().toString().trim()))).doubleValue()/100;
			bVals[2] = ((new Double(b2Adapter.get().toString().trim()))).doubleValue()/100;
			bVals[3] = ((new Double(b3Adapter.get().toString().trim()))).doubleValue()/100;
			bVals[4] = ((new Double(b4Adapter.get().toString().trim()))).doubleValue()/100;
			bVals[5] = ((new Double(b5Adapter.get().toString().trim()))).doubleValue()/100;
			bVals[6] = ((new Double(b6Adapter.get().toString().trim()))).doubleValue()/100;
			bVals[7] = ((new Double(b7Adapter.get().toString().trim()))).doubleValue()/100;
			bVals[8] = ((new Double(b8Adapter.get().toString().trim()))).doubleValue()/100;

			for(int i = 0; i < sVals.length; i++)
			{
				if(sVals[i] < 0 || sVals[i] > 100 || bVals[i] < 0 || bVals[i] > 100)
				{
					throw new Exception("");
				}
			}

			setEnteredRule(new ProbabilisticLifeRule(sVals,bVals,theColorGenerator,"Probabilistic: 1"));
		
		}
		catch(NumberFormatException nex)
		{
			DialogUtil.showMessageDialog("Please only enter numeric values");
		}
		catch(Exception ex)
		{
			DialogUtil.showMessageDialog("Please only enter values 0-100");
		}	

	}
	
	

}
